package com.game.object;

import static org.andengine.extension.physics.box2d.util.constants.PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;

import org.andengine.engine.camera.Camera;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.extension.physics.box2d.PhysicsConnector;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public abstract class GameObject extends AnimatedSprite {

	private boolean rebotable;
	private int xLimitRight;
	private int xLimitLeft;
	private int yLimitUp;
	private int yLimitDown;
	private Body body;
	private PhysicsWorld physicsWorld;
	private Camera camera;
	private float xMaxMetros;
	private float yMaxMetros;
	
	public GameObject(float pX, float pY, ITiledTextureRegion texture,VertexBufferObjectManager vbo, Camera camera, PhysicsWorld physicsWorld)
	{
		super(pX, pY, texture, vbo);
		this.camera = camera;
		this.physicsWorld = physicsWorld;
		this.xMaxMetros = camera.getWidth() / PIXEL_TO_METER_RATIO_DEFAULT;
		this.yMaxMetros = camera.getHeight() / PIXEL_TO_METER_RATIO_DEFAULT;
		createPhysics(this.camera, this.physicsWorld);
		//this.camera.setChaseEntity(this);
	}

	private void createPhysics(final Camera camera, PhysicsWorld physicsWorld)
	{		
		body = PhysicsFactory.createBoxBody(physicsWorld, this, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(0, 0, 0));
		body.setFixedRotation(true);
		
		physicsWorld.registerPhysicsConnector(new PhysicsConnector(this, body, true, false)
		{
			@Override
	        public void onUpdate(float pSecondsElapsed)
	        {
				super.onUpdate(pSecondsElapsed);
				validarGameObjectEnPantalla();
				camera.onUpdate(0.1f);
				move();
				murioEnPantalla();
				
	        }
		});
	}
	
	
	public void jump()
	{
		body.setLinearVelocity(new Vector2(body.getLinearVelocity().x, 12)); 
	}
	
	public void murioEnPantalla()
	{
		
	}
	
	public abstract void move();
	


	public void setNameBody(String name)
	{
		if(body != null)
		{
		body.setUserData(name);
		}
	}
	
	public void pararBody()
	{
		if(body != null)
		{
			body.setLinearVelocity(new Vector2(0,0));
			if(isAnimationRunning() == true)
			{
				stopAnimation();
			}
		}
	}
	
	public void limitarMovimientoEjesGameObject(int xLeft, int xRight, int yUp, int yDown)
	{
		this.xLimitRight = xRight;
		this.xLimitLeft = xLeft;
		this.yLimitUp  = yUp ;
		this.yLimitDown  = yDown;
		
	}
	
	private void validarGameObjectEnPantalla() 
	{
		
		float xMeter = body.getPosition().x;
		float yMeter = body.getPosition().y;
		
		if(xLimitLeft > 0 && xLimitLeft <= camera.getWidth())
		{
			 if (mX < xLimitLeft) { // OutOfScreenX (left)
					
				 body.setTransform(xLimitLeft / PIXEL_TO_METER_RATIO_DEFAULT, yMeter, 0);
				}
		}
		
		if(xLimitRight > 0 && xLimitRight <= camera.getWidth())
		{
			if (mX > xLimitRight) { // OutOfScreenX (right)
				body.setTransform(xLimitRight / PIXEL_TO_METER_RATIO_DEFAULT, yMeter, 0);
			} 	
		}
		
		if(yLimitUp  > 0 && yLimitUp <= camera.getHeight())
		{
			if (mY > yLimitUp) { // OutOfScreenX (right)
				body.setTransform(xMeter, yLimitUp / PIXEL_TO_METER_RATIO_DEFAULT , 0);
			} 	
		}
		
		if(yLimitDown  > 0 && yLimitDown <= camera.getHeight())
		{
			 if (mY < yLimitDown) { // OutOfScreenX (left)
				 body.setTransform(xMeter, yLimitDown / PIXEL_TO_METER_RATIO_DEFAULT , 0);
				}
		}
		
		if(isRebotable() == true)
		{
		if(this.mX < 0) {
			body.setLinearVelocity(body.getLinearVelocity().x, 0);
		} else if(this.mX + this.getWidth() > camera.getWidth()) {
			body.setLinearVelocity(-body.getLinearVelocity().x, 0);
		}

		if(this.mY < 0) {
			body.setLinearVelocity(0, body.getLinearVelocity().y);
		} else if(this.mY + this.getHeight() > camera.getHeight() ) {
			body.setLinearVelocity(0, body.getLinearVelocity().y);
		}

		}
		
		
	/*	
		if (mX > camera.getWidth()) { // OutOfScreenX (right)
			mX = 0;
		} 
		else if (mX < 0) { // OutOfScreenX (left)
			mX = camera.getWidth();
		}
		
		if (mY > camera.getHeight()) { // OutOfScreenX (right)
			mY = 0;
		} 
		else if (mY < camera.getHeight()) { // OutOfScreenX (left)
			mY = camera.getHeight();
		}
		
		if(isRebotable() == true)
		{
		if(this.mX < 0) {
			this.mPhysicsHandler.setVelocityX(this.mPhysicsHandler.getVelocityX());
		} else if(this.mX + this.getWidth() > anchoCamara) {
			this.mPhysicsHandler.setVelocityX(-this.mPhysicsHandler.getVelocityX());
		}

		if(this.mY < 0) {
			this.mPhysicsHandler.setVelocityY(this.mPhysicsHandler.getVelocityY());
		} else if(this.mY + this.getHeight() > largoCamara ) {
			this.mPhysicsHandler.setVelocityY(-this.mPhysicsHandler.getVelocityY());
		}

		}*/
	}


	
	
	public boolean isRebotable() {
		return rebotable;
	}

	public void setRebotable(boolean rebotable) {
		this.rebotable = rebotable;
	}


	public int getxLimitRight() {
		return xLimitRight;
	}


	public void setxLimitRight(int xLimitRight) {
		this.xLimitRight = xLimitRight;
	}


	public int getxLimitLeft() {
		return xLimitLeft;
	}


	public void setxLimitLeft(int xLimitLeft) {
		this.xLimitLeft = xLimitLeft;
	}


	public int getyLimitUp() {
		return yLimitUp;
	}


	public void setyLimitUp(int yLimitUp) {
		this.yLimitUp = yLimitUp;
	}


	public int getyLimitDown() {
		return yLimitDown;
	}


	public void setyLimitDown(int yLimitDown) {
		this.yLimitDown = yLimitDown;
	}

	public Camera getCamera() {
		return camera;
	}

	public void setCamera(Camera camera) {
		this.camera = camera;
	}
	
	
	public void setBody(Body body) {
		this.body = body;
	}
	
	public Body getBody() {
		return body;
	}

	public PhysicsWorld getPhysicsWorld() {
		return physicsWorld;
	}

	public void setPhysicsWorld(PhysicsWorld physicsWorld) {
		this.physicsWorld = physicsWorld;
	}

	public float getxMaxMetros() {
		return xMaxMetros;
	}

	public void setxMaxMetros(float xMaxMetros) {
		this.xMaxMetros = xMaxMetros;
	}

	public float getyMaxMetros() {
		return yMaxMetros;
	}

	public void setyMaxMetros(float yMaxMetros) {
		this.yMaxMetros = yMaxMetros;
	}

}
